package transport

import (
	"bufio"
	"fmt"
	"net"
)

type ClientTCP struct {
	host string
	port int
	pc   *net.TCPConn

	readFunc PacketReadFunc
}

func NewClientTCP(host string, port int, readFunc PacketReadFunc) *ClientTCP {
	return &ClientTCP{
		host:     host,
		port:     port,
		readFunc: readFunc,
	}
}

func (t *ClientTCP) Open() error {
	var (
		host = t.host
		port = t.port
	)

	conn, err := net.DialTCP("tcp4", nil, &net.TCPAddr{
		IP:   net.ParseIP(host),
		Port: port,
	})
	if err != nil {
		return err
	}

	if err = conn.SetReadBuffer(UdpKernelReadBufferSize); err != nil {
		_ = conn.Close()
		return err
	}

	t.pc = conn

	go t.run()

	return nil
}

func (t *ClientTCP) Write(b []byte) (int, error) {
	if t == nil || t.pc == nil {
		return 0, fmt.Errorf("net not open")
	}

	return t.pc.Write(b)
}

func (t *ClientTCP) Close() {
	if t != nil && t.pc != nil {
		_ = t.pc.Close()
	}
}

func (t *ClientTCP) run() {
	var (
		reader     = bufio.NewReader(t.pc)
		rtpOverTCP RtpOverTCP
	)

	for {
		payload, err := rtpOverTCP.ReadRtpOverTCP(reader)
		if err != nil {
			return
		}

		t.readFunc(payload)
	}
}
